package filemanager;

import graphic.LogPanel;
import graphic.MainFrame;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

import javax.swing.JOptionPane;

import utility.Utility;
import core.NetProtocoll;
import core.Server;

public class ConnectedFileTransferSocket {

	Socket user;
	String userId;
	
	String tempDir;
	
	ObjectOutputStream out;
	ObjectInputStream in;
		
	public ConnectedFileTransferSocket(Socket user)
	{	
		try {			
			this.user = user;
			
			String mainDir = Server.getInstance().getConfigs().get(2);
			String temp = Server.getInstance().getConfigs().get(5);
			
			this.tempDir = mainDir + "/" + temp;
			
			this.out = new ObjectOutputStream(this.user.getOutputStream());
			this.out.flush();
			this.in = new ObjectInputStream(this.user.getInputStream());
			
			String message = Utility.readSocketMessage(this.in);
			
			this.userId = message.substring(NetProtocoll.USERID.length());
			FileTransferServerSocket.getInstance().getUsers().put(this.userId, this);
			Utility.sendSocketMessage(NetProtocoll.USERIDOK, this.out);
						
			System.out.println("AGGIUNGO " + this.userId + " ALL' HASH MAP !!");
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/*
	public void sendFile(String filePath, String fileName, String extenzion)
	{
		try {
			File file = new File(filePath + "/" + fileName + "." + extenzion);

			int fileSize = (int)file.length();
			
			String msg = NetProtocoll.STARTFILESENDING;
			msg += fileName + "." + extenzion + ";";
			msg += String.valueOf(fileSize);
			
			Utility.sendSocketMessage(msg, this.out);
			
			byte [] mybytearray  = new byte [fileSize];
			
			FileInputStream fis;
			fis = new FileInputStream(file);
			BufferedInputStream bis = new BufferedInputStream(fis);
			
			bis.read(mybytearray,0,mybytearray.length);
		    OutputStream os = this.user.getOutputStream();
		    os.write(mybytearray,0,mybytearray.length);
		    os.flush();
		    
		    bis.close();
		    
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}*/
	
	public boolean getFile()
	{
		// TODO: Attenzione potrebbe essere avviata dopo l'invio del messaggio da parte del client..
		
		try {
			
			String message = Utility.readSocketMessage(this.in);
			
			System.out.println("RICEVO UN FILE !!! " + message);
			
		    long start = System.currentTimeMillis();
			
			String []parameter = message.substring(NetProtocoll.STARTFILESENDING.length()).split(";");		
			String programName = parameter[0];
			String fileName = parameter[1];
			int fileSize = Integer.parseInt(parameter[2]);
			
			DataOutputStream output;

			BufferedInputStream bis;
			BufferedOutputStream bos;

			byte[] receivedData;
			int in;
			output = new DataOutputStream (this.user.getOutputStream() );
		
			//output.writeUTF("ack 1");

			File dir = new File(this.tempDir + "/" + programName);
			if(!dir.exists())
				dir.mkdir();
			
			receivedData = new byte[1024];
			bis = new BufferedInputStream(this.user.getInputStream());
			bos = new BufferedOutputStream(new FileOutputStream(this.tempDir + "/" + programName  + "/" + fileName));
			
			
			while ((in = bis.read(receivedData)) != -1)
				bos.write(receivedData,0,in);
			
			bos.flush();
			
			bis.close();
			bos.close();
			this.user.close();
			FileTransferServerSocket.getInstance().getUsers().remove(this.userId);
			
			long end = System.currentTimeMillis();
			long time = end - start;
			
			System.out.println("RICEVUTO IL FILE: " + this.tempDir + "/" + programName  + "/" + fileName);
			System.out.println("TEMPO DI TRASFERIMENTO: " + time);
			
			return true;
		} catch (IOException e) {

			try {
				this.user.close();
			} catch (IOException e1) {}
			
			FileTransferServerSocket.getInstance().getUsers().remove(this.userId);
			
			return false;
		}
	}
	
	public boolean sendFile(String programName, String filePath, String fileName, String extenzion)
	{
		try {
	
			File file = new File(filePath + "/" + fileName + "." + extenzion);

			int fileSize = (int)file.length();
			
			if(extenzion.startsWith("r"))
				extenzion = Server.getInstance().getPrograms().get(programName).extenzion;
			
			String msg = NetProtocoll.STARTFILESENDING;
			msg += programName  + ";";
			msg += fileName + "." + extenzion + ";";
			msg += String.valueOf(fileSize);
			
			Utility.sendSocketMessage(msg, this.out);
			
			DataInputStream input;

			BufferedInputStream bis;
			BufferedOutputStream bos;
			int in;
			byte[] byteArray;

			input = new DataInputStream (this.user.getInputStream());
			//System.out.println("Server message: " + input.readUTF());

			//bis = new BufferedInputStream(new FileInputStream("encryptAtmMsg.txt"));
			bis = new BufferedInputStream(new FileInputStream(file));
			bos = new BufferedOutputStream(this.user.getOutputStream());
			
			byteArray = new byte[8192];
			
			while ((in = bis.read(byteArray)) != -1)
				bos.write(byteArray,0,in);
			
			bos.flush();
			
			bis.close();
			bos.close();
			
			this.user.close();
			FileTransferServerSocket.getInstance().getUsers().remove(this.userId);
			
			return true;
			
		} catch (IOException e) {
			
			LogPanel.getInstance().writeLogMessage(LogPanel.SERVER, "Error occurred while sending the file", fileName);
			
			try {
				this.user.close();
			} catch (IOException e1) {}
			
			FileTransferServerSocket.getInstance().getUsers().remove(this.userId);
			
			return false;
		}	
	}
	
	public void close()
	{
		try {
			this.user.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}
